package behavior;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.net.URLClassLoader;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * BehaviorLoader is a class which enables the client application to dynamically
 * load behaviors.  Utilizes a plugin archtecture and instantiates behaviors
 * using the abstract Behavior class implementation.
 *
 * @author      Gabriel Loewen
 *
 */

public class BehaviorLoader {

    // The directory of behavior classes
    private File directory = null;

     /**
     * Constructor.  Takes a file object which identifies a directory of behaviors.
     * @param   dir   The file object which points to the directory of behaviors.
     */
    public BehaviorLoader(File dir) {
        this.directory = dir;
    }
    /**
     * Returns a new behavior from the list of possible behaviors by
     * matching it against an id.
     *
     * @param   id    The id of the requested behavior
     */

    public Behavior getBehavior(String id) {
        ArrayList<Behavior> behaviors = getClasses();
        Behavior behavior = null;
        for (int i=0; i<behaviors.size(); i++) {
            if (behaviors.get(i).getID().equals(id)) {
                behavior = behaviors.get(i);
            }
        }
        return behavior;
    }


     /**
     * Returns an arraylist of classes that are found in the directory.
     */
    public ArrayList getClasses() {
        ArrayList<Behavior> classes = new ArrayList<Behavior>();
        ArrayList<URL> uriList = new ArrayList<URL>();
        if (directory.isDirectory()) {

            File[] files = directory.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].getPath().endsWith(".class") && !files[i].getPath().contains("$")) {
                    try {
                        uriList.add(files[i].toURL());
                    } catch (MalformedURLException ex) {
                    }

                }
            }

            URL[] urls = new URL[uriList.size()];
            urls = uriList.toArray(urls);
            ClassLoader cl = new URLClassLoader(urls);
            String cname = "";
            for (int j = 0; j < uriList.size(); j++) {
                try {
                    String[] fname = uriList.get(j).getFile().split("/");
                    String fIndexedName = fname[fname.length - 1];
                    cname = fIndexedName.substring(0, fIndexedName.length() - 6);
                    Class c = cl.loadClass("behavior." + cname);
                    if (c != null) {
                        Behavior behavior = null;
                        try {
                            behavior = (Behavior) c.newInstance();
                        } catch (InstantiationException ex) {
                            Logger.getLogger(BehaviorLoader.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (IllegalAccessException ex) {
                            Logger.getLogger(BehaviorLoader.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        classes.add(behavior);
                    }
                } catch (ClassNotFoundException ex) {
                    System.out.println(cname + " not found");
                    ex.printStackTrace();
                }
            }
        }
        return classes;
    }
}
